﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WaveEngine.Framework;

namespace WaveEngine.Extensions.ITasks
{
    internal class TaskSetOperationSelector : ITaskSet
    {
        /// <summary>
        /// The parameter
        /// </summary>
        object parameter;

        /// <summary>
        /// The parent
        /// </summary>
        ITask parent;

        /// <summary>
        /// The scene
        /// </summary>
        Scene scene;

        /// <summary>
        /// The name
        /// </summary>
        string Name;

        /// <summary>
        /// Prevents a default instance of the <see cref="TaskSetOperationSelector" /> class from being created.
        /// </summary>
        /// <param name="scene">The scene.</param>
        /// <param name="parameter">The parameter.</param>
        public TaskSetOperationSelector(Scene scene, string name, object parameter)
        {
            this.parameter = parameter;
            this.scene = scene;
            this.Name = name;
        }

        /// <summary>
        /// Prevents a default instance of the <see cref="TaskSetOperationSelector" /> class from being created.
        /// </summary>
        /// <param name="parent">The parent.</param>
        /// <param name="parameter">The parameter.</param>
        public TaskSetOperationSelector(ITask parent, string name, object parameter)
        {
            this.parameter = parameter;
            this.parent = parent;
            this.Name = name;


        }

        /// <summary>
        /// Waits the count.
        /// </summary>
        /// <param name="CountLimit">The count limit.</param>
        /// <returns></returns>
        /// <exception cref="System.NotImplementedException"></exception>
        private ITask WaitCount(int CountLimit)
        {
            if (this.parameter is IEnumerable<Func<ITask>>)
            {
                if (parent == null)
                    return new WaitCountDeferedTaskSet(scene, Name, CountLimit, ((IEnumerable<Func<ITask>>)parameter).ToArray());
                else
                    return new WaitCountDeferedTaskSet(parent, Name, CountLimit, ((IEnumerable<Func<ITask>>)parameter).ToArray());
            }
            else if (this.parameter is IEnumerable<ITask>)
            {
                if (parent == null)
                    return new WaitCountTaskSet(scene, Name, CountLimit, ((IEnumerable<ITask>)parameter).ToArray());
                else
                    return new WaitCountTaskSet(parent, Name, CountLimit, ((IEnumerable<ITask>)parameter).ToArray());
            }
            else
            {
                throw new NotImplementedException();
            }
        }

        /// <summary>
        /// Waits all.
        /// </summary>
        /// <returns></returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public ITask WaitAll()
        {
            int parameterCount = (this.parameter as ICollection).Count;
            return this.WaitCount(parameterCount);
        }

        /// <summary>
        /// Waits any.
        /// </summary>
        /// <returns></returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public ITask WaitAny()
        {
            int parameterCount = (this.parameter as ICollection).Count;
            return this.WaitCount(1);
        }

        /// <summary>
        /// Waits the predicate.
        /// </summary>
        /// <param name="waitingTaskPredicate">The waiting task predicate.</param>
        /// <returns></returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public ITask WaitPredicate(Func<bool, ITask[]> waitingTaskPredicate)
        {
            throw new NotImplementedException();
        }
    }
}
